home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!mcnc!gatech!cwjcc!hal!ncoast!allbery
- From: karl@cs.duke.edu (Karl Ramm)
- Newsgroups: comp.sources.misc
- Subject: v04i042: collected awk/sh/csh/etc. goodies (3 of 3)
- Message-ID: <8808281546.AA09331@romeo.cs.duke.edu>
- Date: 28 Aug 88 15:46:55 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: karl@cs.duke.edu (Karl Ramm)
- Lines: 1036
- Approved: allbery@ncoast.UUCP
-
- Posting-number: Volume 4, Issue 42
- Submitted-by: "Karl Ramm" <karl@cs.duke.edu>
- Archive-name: blachman/Part3
-
- From: Nancy Blachman <decvax!decwrl!sun!idi!resonex!nancy@Ucb-Vax.ARPA>
- To: net.unix, net.unix-wizards, net.sources
- Subject: Actual tricks, shells, csh aliases and the like, 3 of 3
- Date: 16 Oct 84 21:24:32 GMT
- Organization: Resonex Inc., Sunnyvale, CA
-
- > [Know anybody with a GREAT .login or .cshrc?]
-
- > I'm interested in collecting the little tricks, shell scripts, awk
- > hacks, csh aliases, and such that people have built to make their daily
- > life a little easier or more automatic. Being a fairly new system
- > administrator I don't have the big toolbox that years of messing around
- > will leave you with. If you have any hacks you're proud of (or that
- > you aren't proud of, but which work anyway), and you're willing to make
- > them public, mail them to me. I'll collect, collate, shuffle, sort,
- > munge, judge, select and discard them and then "summarize to the net".
-
- This article centers on C programs and awk scripts I received in response to
- my solicitation. The first article concentrates on aliases, and .cshrc and
- .login files. The second article in this series focuses shell scripts.
-
- /\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\/
- > Nancy Blachman {allegra,hplabs,ihnp4,sun}!resonex!nancy (408)720 8600 x37 <
- /\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\/
-
- ::::::::::::::
- programs/1
- ::::::::::::::
- Date: Sat, 15 Sep 84 02:45:08 pdt
- From: <hplabs!intelca!t4test!chip>
- To: intelca!hplabs!resonex!nancy
- Subject: Re: Tricks, shell and awk scripts, csh aliases and the like
-
- One thing I've put together is a bunch of scripts which give you a
- status line on a DEC type terminal. The thing is hardwired into VTxxx
- type stuff rather than termcap for two reasons. First, the cursor
- save/restore function isn't part of termcap. Secondly, the set
- scrolling region is part of termcap, but it is for VT100 type
- terminals. Since we only have DEC terminals, it doesn't hurt us too
- much.
-
- Some history: I used to like to display my current working directory
- on my prompt line. Later I wanted my terminal line there too. (That
- was in case a terminal I was on locked up, I could quickly tell what
- terminal to kill.) Later, when I had four accounts on the machine I
- thought it would be nice to display my login name in my prompt. The
- straw which broke the camel's back was that we bought another VAX, and
- I wanted to be able to see which machine I was logged on. As you might
- imagine, my prompt now extended about 60 columns across the screen. My
- answer was to take everything out of my prompt except the history
- number and stick it at a status line at the bottom of my screen.
-
- Below is a shar archive of the status line files. You do a `source
- stat.init' to get stuff initialized. Then `son' and `soff' (which are
- aliased to source the two other scripts) turn the status line on and
- off. These also define a bunch of aliases which help you work with
- programs which don't like the status line. So, I put a `source
- /usr/public/stat.init' followed by a `son' in my `.login'. (I don't
- turn it on with my `.cshrc', my shell escapes would then get awfully
- sloooooow.)
-
- Also, you would need to add `vt100s' and `vt131s' to /etc/termcap.
- This is to keep screen stuff (e.g. more, vi, etc.) happy if you run
- them with the status line on. This is what I use:
-
- ################ VT131 with 24th line reserved
- ################ d13s|vt131s|VT131S|vt-131s|pt131s|pt-131s|dec
- vt131s:\
- :li#23:tc=vt131
-
- You will definately want to change the terminal identification stuff in
- `stat.init'. We run Eunice, so I use the `grep' to convert the Unix
- style terminal line identification to a VMS terminal port.
-
- You can redefine `statin' in the `stat.init' script to put whatever you
- want on the status line.
-
- Well...after all this, I hope you use VT1xx/VT2xx terminals.
- Otherwise, this won't be real exciting. (Unless you want to rewrite
- `statterm.c')
-
- ---
-
- Chip Rosenthal, Intel/Santa Clara
- { idi|intelca|icalqa|kremvax|qubix|ucscc } ! t4test ! { chip|news }
-
- ----- cut here -----------------------------------------------------------
-
- : This is a shar archive. Extract with sh, not csh.
- : This archive contains the following files
- : Makefile stat.init stat.on stat.off statterm.c
- : Total number of files: 5
- echo x - Makefile [file 1 of 5]
- sed 's/^|//' > Makefile << '!-FUNKY-STUFF-!'
- |BIN= /usr/public
- |OBJS= statterm
- |
- |IOBJS= $(BIN)/statterm \
- | $(BIN)/stat.init \
- | $(BIN)/stat.on \
- | $(BIN)/stat.off
- |
- |SOURCES=Makefile \
- | stat.init \
- | stat.on \
- | stat.off \
- | statterm.c
- |
- |all: $(OBJS)
- |install: $(IOBJS)
- |shar: stat.shar
- |
- |statterm: statterm.c
- | cc -O statterm.c -o statterm
- |
- |$(BIN)/statterm: statterm
- | cp $? $@
- | chmod 755 $@
- |
- |$(BIN)/stat.init: stat.init
- | cp $? $@
- | chmod 755 $@
- |
- |$(BIN)/stat.on: stat.on
- | cp $? $@
- | chmod 755 $@
- |
- |$(BIN)/stat.off: stat.off
- | cp $? $@
- | chmod 755 $@
- |
- |stat.shar: $(SOURCES)
- | shar $(SOURCES) > $@
- |
- |
- !-FUNKY-STUFF-!
- echo x - stat.init [file 2 of 5]
- sed 's/^|//' > stat.init << '!-FUNKY-STUFF-!'
- |alias a 'alias'
- |
- |# run statterm to verify terminal can do status line
- |statterm
- |if $status then
- | # status line not available on this terminal -- see if a
- | # baseterm is defined. if so, then maybe $TERM is just
- | # messed up from earlier invocation of stat.init.
- | if $?baseterm then
- | # baseterm has been defined -- see if it will work
- | set temp=$TERM
- | setenv TERM $baseterm
- | statterm
- | if $status then
- | # nope -- baseterm will not work either
- | setenv TERM $temp
- | unset temp
- | goto failed
- | else
- | # yes -- baseterm will work
- | echo "changing terminal type from $temp to $TERM"
- | unset temp
- | endif
- | else
- | # no baseterm defined
- | goto failed
- | endif
- |endif
- |
- |# status line will work with this terminal
- |set baseterm=$TERM
- |set ignoreeof
- |
- |# find user's system (ick)
- |set system=`tr '[A-Z]' '[a-z]' < /usr/include/whoami`
- |
- |# find user's tty (ick ick ick)
- |set temp=`tty`'$'
- |set tty=`grep "$temp" /etc/dev.com | sed -e 's/^.*_\(.*\):.*/\1/'`
- |unset temp
- |
- |# setup terminal strings
- |set statin="`statterm in '${system}\\!${user}' '(${tty})'`"
- |set statout="`statterm out`"
- |set statoff="`statterm off`"
- |echo -n "$statoff"
- |
- |# setup status commands
- |# son - turn on status mode
- |# soff - turn off status mode
- |# stat - draw status line
- |# nostat - erase status line
- |# termstat - setenv the terminal with status line protected
- |# termnorm - setenv the terminal without a status line
- |# ns - execute a command without a status line
- |a son 'source /usr/public/stat.on'
- |a soff 'source /usr/public/stat.off'
- |a stat ';'
- |a nostat ';'
- |a termstat ';'
- |a termnorm ';'
- |a ns 'nostat ; termnorm ; \!* ; termstat ; stat ; echo ""'
- |
- |# alias the commands which maintain the status line
- |a cd 'chdir \!* ; stat'
- |a popd 'popd ; stat'
- |a pushd 'pushd \!* ; stat'
- |
- |# alias the commands which (might) munch the status line
- |a clear 'clear \!* ; stat'
- |a mail 'mail \!* ; stat'
- |a more 'more \!* ; stat'
- |
- |# alias the commands which should be done with the status line off
- |a lo 'ns logout \!*'
- |a LO 'ns logout \!*'
- |a rn 'ns /local/bin/rn \!*'
- |a pn 'ns /local/bin/pn \!*'
- |a reply 'ns /local/bin/reply \!*'
- |a sus 'ns suspend \!*'
- |a vi 'ns /usr/ucb/vi \!*'
- |a view 'ns /usr/ucb/view \!*'
- |
- |# that is all folks. the status stuff is initialized
- |# now all you need is a 'son' to turn it on
- |exit 0
- |
- |failed:
- |set baseterm=$TERM
- |set temp="status line is not available for terminal type $TERM"
- |echo $temp
- |set statin=";"
- |set statout=";"
- |if $?statoff == 0 then
- | set statoff=";"
- |endif
- |alias son echo "$temp"
- |alias off 'source /usr/public/stat.off'
- |unset temp
- |soff
- |exit 1
- |
- !-FUNKY-STUFF-!
- echo x - stat.on [file 3 of 5]
- sed 's/^|//' > stat.on << '!-FUNKY-STUFF-!'
- |a stat 'echo -n "${statin}${cwd}${statout}"'
- |a nostat 'echo -n "$statoff"'
- |a termstat 'setenv TERM ${baseterm}s'
- |a termnorm 'setenv TERM $baseterm'
- |termstat
- |stat
- |echo ""
- |set statmode
- !-FUNKY-STUFF-!
- echo x - stat.off [file 4 of 5]
- sed 's/^|//' > stat.off << '!-FUNKY-STUFF-!'
- |setenv TERM $baseterm
- |echo -n "$statoff"
- |unset statmode
- |a termstat ';'
- |a termnorm ';'
- |a stat ';'
- |a nostat ';'
- !-FUNKY-STUFF-!
- echo x - statterm.c [file 5 of 5]
- sed 's/^|//' > statterm.c << '!-FUNKY-STUFF-!'
- |/*
- | * FILE: statterm
- | * VERSION: V0.01 [preliminary]
- | * DATE: Mon Aug 27 16:43:13 PDT 1984
- | * AUTHOR: Chip Rosenthal/Intel Corporation
- | * ADDRESS: t4test!chip
- | * PACKAGE: 'stat' terminal status line package
- | * DESCRIPTION: produces terminal escape sequences to implement status line
- | * COMPILATION: cc -C statterm.c -o statterm
- | *
- | * REVISION NOTES:
- | *
- | * V1.00 Original program.
- | *
- | *
- | * USAGE:
- | *
- | * statterm
- | * Verifies that the status line will work with current terminal.
- | * Returns a zero exit status if it will, nonzero if it won't.
- | *
- | * statterm in [arg ...]
- | * Creates a string which opens up the status line. Any
- | * arguments are placed at the beginning of the status
- | * line, and the cursor is left there.
- | *
- | * statterm out
- | * Create string which closes the status line and returns
- | * cursor to position it was in prior to the last execution
- | * of a 'statterm in' string.
- | *
- | * statterm off
- | * Creates a string which removes the status line.
- | *
- | *
- | * EXAMPLE:
- | * # this is a cshell script
- | * statterm
- | * if $status then
- | * echo "status line will not work on this terminal"
- | * exit
- | * endif
- | * echo -n `statterm in $user`
- | * echo -n `pwd`
- | * echo `statterm out`
- | *
- | *
- | * BUGS:
- | *
- | * This program is hardwired into the DEC VT100 terminal escape sequences.
- | * This is done because (unfortunately) 'termcap' doesn't offer a cursor
- | * position save/restore feature.
- | *
- | */
- |
- |#include <stdio.h>
- |#define strmatch(A,B) (strcmp((A),(B))==0)
- |
- |/*
- | * VT100 Terminal Escape Definitions -- all parameters are strings
- | */
- |#define ESC putchar(27); /* escape character */
- |#define CSI ESC;putchar('['); /* command string */
- |#define DECSC ESC;putchar('7'); /* save cursor position */
- |#define DECRC ESC;putchar('8'); /* restore cursor position */
- |#define CUP(L,C) CSI;printf("%s;%sH",L,C); /* set cursor to line/col */
- |#define CUU1 CSI;printf("1A"); /* cursor up one line */
- |#define CUD1 CSI;printf("1B"); /* cursor down one line */
- |#define EL(MODE) CSI;printf("%sK",MODE); /* erase line */
- |#define ED(MODE) CSI;printf("%sJ",MODE); /* erase display */
- |#define DECSETBM(T,B) CSI;printf("%s;%sr",T,B); /* top/bot of scroll area */
- |/*
- | * erasing modes:
- | * mode "0" - from cursor to end
- | * mode "1" - from beginning to cursor
- | * mode "2" - entire
- | */
- |
- |
- |main(argc,argv)
- |int argc;
- |char *argv[];
- |{
- | char *term, *getenv();
- | int i;
- |
- | if ( argc == 1 ) {
- | term=getenv("TERM");
- | if ( term == NULL )
- | exit(1);
- | if ( strmatch(term,"vt100") || strmatch(term,"vt131") )
- | exit(0);
- | else
- | exit(1);
- | }
- |
- | if ( strmatch(argv[1],"in") ) {
- | /*
- | * Save cursor position, go to line 24, print out the arguments, and
- | * erase the rest of the status line. Cursor remains in status line.
- | */
- | DECSC;
- | CUP("24","1");
- | for ( i=2 ; i<argc ; ++i )
- | printf("%s ",argv[i]);
- | EL("0");
- | } else if ( strmatch(argv[1],"out") ) {
- | /*
- | * Protect status line from scrolling and restore cursor to location
- | * prior to the last 'in' call. Move the cursor up and down one line.
- | * This will keep it out of the status line area if it was there when
- | * 'in' was called.
- | */
- | DECSETBM("1","23");
- | DECRC;
- | CUU1;
- | CUD1;
- | } else if ( strmatch(argv[1],"off") ) {
- | /*
- | * Save the current cursor position, unprotect the status line, erase
- | * the status line, and restore the cursor position.
- | */
- | DECSC;
- | DECSETBM("1","24");
- | CUP("24","1");
- | EL("2");
- | DECRC;
- | } else
- | exit(1);
- |
- |}
- !-FUNKY-STUFF-!
- exit
-
-
-
- ::::::::::::::
- programs/2
- ::::::::::::::
- From: ihnp4!mcnc!malloy@ittral
- Date: Thu, 13 Sep 84 21:35:18 edt
- To: ihnp4!resonex!nancy@mcnc
- Subject: Tricks
-
- Well it depends upon what you mean. The big problem with having lots of aliases
- and such is they start taking up large amounts of memory. Take it from someone
- who knows. But here's a few things. Some you no doubt already have, and most
- are trivial, but it's better to be complete then to leave anything out. You
- can always just delete this. == William P. Malloy (ittral!malloy}
- ---------------------------------------------------------------------
- In a .cshrc, a warning and a work around. Apparently not known by most people
- but obvious to people have who been around. Our users keep bumping into it
- about once a year like clock work.
- # reason for setting variables only if a prompt already exists
- # If it sets prompt in a non-interactive shell, for instance vi(1)
- # firing up a sub-shell to expand shell meta-characters, the set prompt
- # will stomp on alot of shell variables used for the expansion (like ~)
- #
- if ( $?prompt ) then
- set mail=/usr/spool/mail/malloy
- set prompt=\`
- set histchars=",;"
- endif
- Note the setting of histchars. A little known, but for me much loved feature
- of csh is the ability to change the history characters "!^" from their default
- values. The pair `,;' are easier to reach, don't require shifting, and don't
- appear in mail paths. Typing `mail mcnc\!ihnp4\!resonex\!nancy' gets to be
- a pain every time you want to mail someone.
-
- alias , 'redo \,* ~/.cmd ~/.cmd1 ; source ~/.cmd1 '
-
- This little alias allows you to have command editing in the csh. It's quite
- useful, particularly when you've got a LONG painful command line. The , is
- just the history character and is ! for most people. The command redo is a
- simple C program.
- --------------- redo.c -------------------
- #include <stdio.h>
-
- /* redo -- outputs a command file (last arg )used to edit and
- re-ex a command. Next to last arg is dest file of the command.
-
- NOTE: if you use a non-standard history character, i.e. not !
- then you must `setenv HISTCHARS $histchars' in your .login
- If you do not `set histchars=",;"' for instance then it will
- automagically default to ! -- 12/2/83 wpm
-
- First arg is the history ref . To use:
- alias , 'redo \,* ~/cmd ~/cmd1 ; source ~/cmd1 '
- , 25 to edit & re-execute ,25
- , , or , to edit & re-execute ,,
- , v to edit & re-execute ,v ,etc.
-
- */
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- FILE *fp;
- char *t, *getenv();
-
- fp = fopen(argv[argc-1], "w");
- if ((t = getenv("HISTCHARS")) != NULL)
- t[1] = '\0';
- else
- t = "!";
- fprintf(fp, "echo \"%s", t);
- if ( (argc < 4) || (strcmp(argv[1], t) == 0) )
- fputs("-2", fp);
- else
- fputs(argv[1], fp);
- fputs(":q\" >! ", fp);
- fputs(argv[argc-2], fp);
- putc('\n', fp);
- fputs("ex +open ", fp);
- fputs(argv[argc-2], fp);
- putc('\n', fp);
- fputs("/usr/local/typein2 < ", fp);
- fputs(argv[argc-2], fp);
- putc('\n', fp);
- fclose(fp);
- exit(0);
- }
- ------------------ (end of redo.c, begining of typein2.c) --------------------
- #include <stdio.h>
- #include <sgtty.h>
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- register char *cp;
- struct sgttyb stb, stb2;
- int pendin = LPENDIN;
- int c,i,j;
- char buff[2];
- char buff2[256];
-
- i=0;
- while ((c=getchar()) != EOF) {
- buff2[i++]=c;
- }
- ioctl(2, TIOCGETP, &stb);
- stb2 = stb;
- stb.sg_flags &= ~ECHO;
- ioctl(2, TIOCSETN, &stb);
- for (j=0; j<i; j++) {
- ioctl(2, TIOCSTI, &buff2[j]);
- putchar(buff2[j]);
- }
- ioctl(2, TIOCSETN, &stb2);
- ioctl(2, TIOCLBIS, &pendin);
- exit(0);
- }
- ---------------------------- (end of typein2.c) ------------------------
- A couple of oldies but still the simplest. cd and back aliases.
- alias back 'set back=$old; set old=$cwd; cd $back; unset back; dirs'
- alias cd 'set old=$cwd; chdir \,*; set prompt = "< $cwd:t > "'
-
- # this is a useful feature for vi
- setenv EXINIT 'map #1 Gi/\<A\>"add@a|map #2 1G\!Gvispell|set ai sw=3'
-
- You f2 key will run a file through the spell program, and put the words it
- doesn't find in the dictionary at the bottom of the file. Then typing f1 will
- cause it to delete the last line in the file, and search for the string in
- the rest of the file.
- ------------------------------ (source for vispell) -------------
- #! /bin/sh
- #
- tee /tmp/vis$$
- echo SpellingList
- spell /tmp/vis$$
- rm /tmp/vis$$
- ------------------------------- (end of vispell) ------------------
- Stuff from our /.cshrc file. psa lets you see what's going on in the system
- and what people are doing. Useful to see if people are hanging themselves.
- alias psa 'ps axu | sed "/getty/d" | sort -f | more'
-
- A simple alias to compile C programs (C adm.c expands to cc adm.c -o adm).
- alias C 'cc \,:* -o \,^:r'
-
- Useful to see what's going on in the system without those !@#$% bells.
- alias moremsgs "tr -d '\07' </usr/adm/messages | more"
-
- Like fg.
- alias pj '%-'
-
- A feature we use in our root .cshrc allowing indivual superusers to get their
- own enviornment. Useful if people want their own enviornment anywhere people
- share an account.
- if ( $user == "malloy" ) then
- source /t/malloy/.root
- endif
-
- --------------- (here's some things I picked up off the net) --------------
- From: ittvax!decvax!harpo!utah-cs!seismo!hao!denelcor!udenva!koala!aburt
- Date: Fri Aug 10 09:19:37 1984
- Subject: Perversions of source -h and other csh aliases
- Newsgroups: net.unix,net.unix-wizards,net.sources
-
- For your enjoyment, here are some interesting lunch hour csh aliases that
- I've created.
- {this is to slow, my version is a little faster}
- My personal favorite is the "history editor" -- allows you to edit
- you csh history. The alias:
-
- alias hed history -h !* > $hed; vi + $hed; source -h $hed
-
- will allow you to invoke 'vi' on your current history. (If, for
- instance, you typed in a long, tedious line and put in an extra space,
- among other things. The ^...^... mechanism to remove it can be quite
- tedious; 'hed's is easy.) Before anyone starts flaming that vi is too
- slow, history can do it (even if it's tough to type and you're prone to
- more typos doing the history), etc. -- if you don't like it, don't use it.
-
- Hed works particularly well if you move the command in question to the
- end of the file; then '!!' will execute it after you ZZ from vi. The
- only drawback to this is that it trashes your current event numbers
- (they get incremented during the source -h). By using 'hed 10' you
- only edit the last 10 entries in your history. A temp file, which I
- keep in $hed (set to /tmp/hed.$$ from my .login), is used each time for
- the history. Obvious changes to this are to use /tmp/hed.$$ straight
- out and add "rm /tmp/hed.$$" to the end of the list. If you don't like
- waiting for the rm, and your /tmp doesn't get cleared out periodically,
- put a # in front of the name to make it a disposable file.
-
- This may be slower than the vi/emacs mode in the ksh I keep hearing about, but
- it does give the functionality.
-
- A slight modification to 'hed'...
-
- alias hedf history -h !-0:1 > !-0:2; vi + !-0:2; source -h !-0:2
-
- allows you to specify a file to place the history into instead of a temp
- file.
-
- Another modification yields:
-
- alias heh echo \!* > $hed; vi + $hed; source -h $hed
-
- Which lets you edit then add to your history a specific history sequence.
- 'Heh' for History edit history.
-
- By inserting a 'source \!-0:2' before the source -h in any of the
- above has the effect of executing the commands AND placing them on the
- history list (from which we may conclude that 'alias so source \!* ;
- source -h \!*' is a useful item: it sources a file then places each line
- into your history).
-
- On rare occasions you'll have to put extra quotes/escapes around things
- when editing the temp file so it gets sourced right. Particularly around
- aliases with raw history substitutions in them (the \!* type of thing).
- The easiest is to try it first; if it fails, edit it again. After all,
- two 'hed's are better than one...
-
- Regarding the use of !-0:1 instead of !:1 for the first argument to the
- current command -- At least one csh is known to accept the former but not
- the latter. (The same csh dumps core (therefore logging you out) on receipt
- of the !# history selector. This is version 1.0 of 4.2BSD csh on a Sun-2.
- The 1.1 csh exhibits this behavior:
-
- echo a !#
- a echo a echo
-
- adding an extra arg 0 to the end. Is this common to other cshs out there?)
-
- So, for those whose csh's allow !:1, use that where I have !-0:1, etc.
-
- Another interesting perversion is an alias'd whereis:
-
- alias wheres ls -l \{'`echo $path | sed "s/ /,/g"`'\}/'`echo \!-0:1 | sed "s/^./[&]/"`'
-
- It does an ls -l on every file (passed as arg 1) in any directory on
- your current path. (No aliases, though adding an if at the front
- should do the trick.) The idea is to turn your $path list into a comma
- separates list, stick that between {}, and append / and arg 1 to that.
- Alas, if the file doesn't exist in one of the directories, you get
- errors from ls saying it doesn't exist in a given directory. So, arg 1
- is turned into a pattern, which is allowed to fail; the pattern is,
- e.g., foo --> [f]oo. So the second arg to ls only expands to the
- existing files.
- ---------------------------- (end of net article) ------------------------
- --
- Address: William P. Malloy, ITT Telecom, B & CC Engineering Group, Raleigh NC
- {ihnp4!mcnc, burl, ncsu, decvax!ittvax}!ittral!malloy
-
-
- ::::::::::::::
- awk/1
- ::::::::::::::
- Date: Wed, 19 Sep 84 11:44:38 CST
- From: David Chase <hplabs!ucbvax!rbbb@rice.ARPA>
- Subject: Re: Tricks, shell and awk scripts, csh aliases and the like
- To: resonex!nancy@BERKELEY
-
- Here is my favorite awk script. It turns a list of csrc's from memory
- errors on an 11/780 (with MS780C controller) into board and chip position
- for certain Mostek memory boards. This script saved me many headaches,
- because the tables in the appendix of the technical manual were hard to read
- and contained errors (errors that were noticed as deviations from a pattern
- when entering this script).
-
- #
- # Incredible sleazy awk file to attack memory errors
- # Included here is the local configuration, because some decoding
- # is board specific
- #
- BEGIN {
- # Boards understood by this program
-
- # mk4118 = mostek mk8016 fully populated with mk4116 chips (512k)
- known["mk4118"] = 1
-
- # mk4116 = mostek mk8016 half populated with mk4116 chips (256k)
- known["mk4116"] = 1
-
- # mk8016 = mostek mk8016 fully populated with mk4108 chips (256k)
- known["mk4108"] = 1
-
- # m8210 = DEC 256k board; don't know how to decode this guy (256k)
- known["m8210"] = 0
-
- # To add different boards, (i.e., not conforming to this system)
- # append to the "pos" map, and make "keys[<array><bank><new board>]"
- # reference the appended chip addresses.
-
- # Local configuration
- # boards is indexed by slot number
- boards["0"] = "m8210"
- boards["1"] = "m8210"
- boards["2"] = "m8210"
- boards["3"] = "m8210"
- boards["4"] = "m8210"
- boards["5"] = "m8210"
- boards["6"] = "mk4116"
- boards["7"] = "mk4116"
- boards["8"] = "mk4116"
- boards["9"] = "mk4116"
- boards["a"] = "mk4116"
- boards["b"] = "mk4116"
- boards["c"] = "mk4118"
- boards["d"] = "mk4118"
- boards["e"] = "mk4118"
- boards["f"] = "mk4118"
-
- # bit in error for a given CRC calculation
- # bits are identified by "u" (upper), "l" (lower), and "c" (check)
- # folowed by the bit number.
-
- bit["01"] = "c0"
- bit["02"] = "c1"
- bit["04"] = "c2"
- bit["08"] = "c3"
- bit["10"] = "c4"
- bit["19"] = "l01"
- bit["1a"] = "l02"
- bit["1c"] = "l04"
- bit["1f"] = "l07"
- bit["20"] = "c5"
- bit["38"] = "l00"
- bit["3b"] = "l03"
- bit["3d"] = "l05"
- bit["3e"] = "l06"
- bit["40"] = "c6"
- bit["49"] = "l09"
- bit["4a"] = "l10"
- bit["4c"] = "l12"
- bit["4f"] = "l15"
- bit["51"] = "l17"
- bit["52"] = "l18"
- bit["54"] = "l20"
- bit["57"] = "l23"
- bit["58"] = "l24"
- bit["5b"] = "l27"
- bit["5d"] = "l29"
- bit["5e"] = "l30"
- bit["68"] = "l08"
- bit["6b"] = "l11"
- bit["6d"] = "l13"
- bit["6e"] = "l14"
- bit["70"] = "l16"
- bit["73"] = "l19"
- bit["75"] = "l21"
- bit["76"] = "l22"
- bit["79"] = "l25"
- bit["7a"] = "l26"
- bit["7c"] = "l28"
- bit["7e"] = "l31"
- bit["80"] = "c7"
- bit["89"] = "u01"
- bit["8a"] = "u02"
- bit["8c"] = "u04"
- bit["8f"] = "u07"
- bit["91"] = "u09"
- bit["92"] = "u10"
- bit["94"] = "u12"
- bit["97"] = "u15"
- bit["98"] = "u16"
- bit["9b"] = "u19"
- bit["9d"] = "u21"
- bit["9e"] = "u22"
- bit["a8"] = "u00"
- bit["ab"] = "u03"
- bit["ad"] = "u05"
- bit["ae"] = "u06"
- bit["b0"] = "u08"
- bit["b3"] = "u11"
- bit["b5"] = "u13"
- bit["b6"] = "u14"
- bit["b9"] = "u17"
- bit["ba"] = "u18"
- bit["bc"] = "u20"
- bit["bf"] = "u23"
- bit["c1"] = "u25"
- bit["c2"] = "u26"
- bit["c4"] = "u28"
- bit["c7"] = "u31"
- bit["e0"] = "u24"
- bit["e3"] = "u27"
- bit["e5"] = "u29"
- bit["e6"] = "u30"
-
- # binary decoding of hex digits
-
- hex["0"] = "0000"
- hex["1"] = "0001"
- hex["2"] = "0010"
- hex["3"] = "0011"
- hex["4"] = "0100"
- hex["5"] = "0101"
- hex["6"] = "0110"
- hex["7"] = "0111"
- hex["8"] = "1000"
- hex["9"] = "1001"
- hex["a"] = "1010"
- hex["b"] = "1011"
- hex["c"] = "1100"
- hex["d"] = "1101"
- hex["e"] = "1110"
- hex["f"] = "1111"
-
- # chip positions for a given bit, collected across all possible
- # boards. Each group of 3 letters represents a position.
- # See keys for a better description.
-
- pos["u31"] = "i01h01g01f01"
- pos["u30"] = "e01d01c01b01"
- pos["u29"] = "i02h02g02f02"
- pos["u28"] = "e02d02c02b02"
- pos["u27"] = "i03h03g03f03"
- pos["u26"] = "e03d03c03b03"
- pos["u25"] = "i04h04g04f04"
- pos["u24"] = "e04d04c04b04"
- pos["u23"] = "a01a02a03a04"
- pos["u22"] = "i05h05g05f05"
- pos["u21"] = "e05d05c05b05"
- pos["u20"] = "i06h06g06f06"
- pos["u19"] = "e06d06c06b06"
- pos["u18"] = "i07h07g07f07"
- pos["u17"] = "e07d07c07b07"
- pos["u16"] = "i08h08g08f08"
- pos["u15"] = "e08d08c08b08"
- pos["u14"] = "a05a06a07a08"
- pos["u13"] = "i09h09g09f09"
- pos["u12"] = "e09d09c09b09"
- pos["u11"] = "i10h10g10f10"
- pos["u10"] = "e10d10c10b10"
- pos["u09"] = "i11h11g11f11"
- pos["u08"] = "e11d11c11b11"
- pos["u07"] = "i12h12g12f12"
- pos["u06"] = "e12d12c12b12"
- pos["u05"] = "a09a10a11a12"
- pos["u04"] = "i13h13g13f13"
- pos["u03"] = "e13d13c13b13"
- pos["u02"] = "i14h14g14f14"
- pos["u01"] = "e14d14c14b14"
- pos["u00"] = "i15h15g15f15"
- pos["c7"] = "e15d15c15b15"
- pos["c6"] = "i16h16g16f16"
- pos["c5"] = "e16d16c16b16"
- pos["c4"] = "a13a14a15a16"
- pos["l31"] = "i17h17g17f17"
- pos["l30"] = "e17d17c17b17"
- pos["l29"] = "i18h18g18f18"
- pos["l28"] = "e18d18c18b18"
- pos["l27"] = "i19h19g19f19"
- pos["l26"] = "e19d19c19b19"
- pos["l25"] = "i20h20g20f20"
- pos["l24"] = "e20d20c20b20"
- pos["l23"] = "a17a18a19a20"
- pos["l22"] = "i21h21g21f21"
- pos["l21"] = "e21d21c21b21"
- pos["l20"] = "i22h22g22f22"
- pos["l19"] = "e22d22c22b22"
- pos["l18"] = "i23h23g23f23"
- pos["l17"] = "e23d23c23b23"
- pos["l16"] = "i24h24g24f24"
- pos["l15"] = "e24d24c24b24"
- pos["l14"] = "a21a22a23a24"
- pos["l13"] = "i25h25g25f25"
- pos["l12"] = "e25d25c25b25"
- pos["l11"] = "i26h26g26f26"
- pos["l10"] = "e26d26c26b26"
- pos["l09"] = "i27h27g27f27"
- pos["l08"] = "e27d27c27b27"
- pos["l07"] = "i28h28g28f28"
- pos["l06"] = "e28d28c28b28"
- pos["l05"] = "a25a26a27a28"
- pos["l04"] = "i29h29g29f29"
- pos["l03"] = "e29d29c29b29"
- pos["l02"] = "i30h30g30f30"
- pos["l01"] = "e30d30c30b30"
- pos["l00"] = "i31h31g31f31"
- pos["c3"] = "e31d31c31b31"
- pos["c2"] = "i32h32g32f32"
- pos["c1"] = "e32d32c32b32"
- pos["c0"] = "a29a30a31a32"
-
- # keys is indexed by <board #> <bank> <board type>
- # and yields an index into a particular pos string
- # for example, board 0, bit 0 on an mk4118 board
- # gives a key of 4. If the bit in error was c0, then
- # the chip in error is a32 (from the 4th group of 3
- # in pos["c0"]. To change this map, create new keys
- # and (if necessary) append to the pos entries.
- # If it could be more than one chip, then use a multiple
- # digit key (e.g, see the keys for the mk4108 board).
-
- keys["00mk4118"] = "4"
- keys["20mk4118"] = "4"
- keys["40mk4118"] = "4"
- keys["60mk4118"] = "4"
- keys["80mk4118"] = "4"
- keys["a0mk4118"] = "4"
- keys["c0mk4118"] = "4"
- keys["e0mk4118"] = "4"
- keys["01mk4118"] = "2"
- keys["21mk4118"] = "2"
- keys["41mk4118"] = "2"
- keys["61mk4118"] = "2"
- keys["81mk4118"] = "2"
- keys["a1mk4118"] = "2"
- keys["c1mk4118"] = "2"
- keys["e1mk4118"] = "2"
- keys["10mk4118"] = "3"
- keys["30mk4118"] = "3"
- keys["50mk4118"] = "3"
- keys["70mk4118"] = "3"
- keys["90mk4118"] = "3"
- keys["b0mk4118"] = "3"
- keys["d0mk4118"] = "3"
- keys["f0mk4118"] = "3"
- keys["11mk4118"] = "1"
- keys["31mk4118"] = "1"
- keys["51mk4118"] = "1"
- keys["71mk4118"] = "1"
- keys["91mk4118"] = "1"
- keys["b1mk4118"] = "1"
- keys["d1mk4118"] = "1"
- keys["f1mk4118"] = "1"
-
- keys["00mk4116"] = "4"
- keys["20mk4116"] = "4"
- keys["40mk4116"] = "4"
- keys["60mk4116"] = "4"
- keys["80mk4116"] = "4"
- keys["a0mk4116"] = "4"
- keys["c0mk4116"] = "4"
- keys["e0mk4116"] = "4"
- keys["01mk4116"] = "2"
- keys["21mk4116"] = "2"
- keys["41mk4116"] = "2"
- keys["61mk4116"] = "2"
- keys["81mk4116"] = "2"
- keys["a1mk4116"] = "2"
- keys["c1mk4116"] = "2"
- keys["e1mk4116"] = "2"
- keys["10mk4116"] = "4"
- keys["30mk4116"] = "4"
- keys["50mk4116"] = "4"
- keys["70mk4116"] = "4"
- keys["90mk4116"] = "4"
- keys["b0mk4116"] = "4"
- keys["d0mk4116"] = "4"
- keys["f0mk4116"] = "4"
- keys["11mk4116"] = "2"
- keys["31mk4116"] = "2"
- keys["51mk4116"] = "2"
- keys["71mk4116"] = "2"
- keys["91mk4116"] = "2"
- keys["b1mk4116"] = "2"
- keys["d1mk4116"] = "2"
- keys["f1mk4116"] = "2"
-
- keys["00mk4108"] = "34"
- keys["20mk4108"] = "34"
- keys["40mk4108"] = "34"
- keys["60mk4108"] = "34"
- keys["80mk4108"] = "34"
- keys["a0mk4108"] = "34"
- keys["c0mk4108"] = "34"
- keys["e0mk4108"] = "34"
- keys["01mk4108"] = "12"
- keys["21mk4108"] = "12"
- keys["41mk4108"] = "12"
- keys["61mk4108"] = "12"
- keys["81mk4108"] = "12"
- keys["a1mk4108"] = "12"
- keys["c1mk4108"] = "12"
- keys["e1mk4108"] = "12"
- keys["10mk4108"] = "34"
- keys["30mk4108"] = "34"
- keys["50mk4108"] = "34"
- keys["70mk4108"] = "34"
- keys["90mk4108"] = "34"
- keys["b0mk4108"] = "34"
- keys["d0mk4108"] = "34"
- keys["f0mk4108"] = "34"
- keys["11mk4108"] = "12"
- keys["31mk4108"] = "12"
- keys["51mk4108"] = "12"
- keys["71mk4108"] = "12"
- keys["91mk4108"] = "12"
- keys["b1mk4108"] = "12"
- keys["d1mk4108"] = "12"
- keys["f1mk4108"] = "12"
- }
-
- {csrc = $1
- syndrome = substr (csrc,7,2)
- board = substr (csrc,2,1)
- boardtype = boards[board]
- bank = substr (hex [substr (csrc,3,1)],1,1)
- chips = bit[syndrome]
- if (known[boardtype])
- { where = pos[chips]
- key = keys[board bank boardtype]
- sbegin = 3 * (substr(key,1,1) - 1) + 1
- thechip = substr(where,sbegin,3)
- if (length(key) > 1)
- { sbegin = 3 * (substr(key,2,1) - 1) + 1
- thechip = thechip " and/or " substr(where,sbegin,3)
- }
- # printf "\n"
- # print "csrc = " csrc
- # print "syndrome = " syndrome
- # print "board = " board
- # print "bank = " bank
- # print "chips = " chips
- # print "locations = " where
- # print "boardtype = " boardtype
- # print "key = " key
- # print "the chip is " thechip
- errors[board "-" thechip]++;
- }
- else
- {
- # printf "\n"
- # print "Board type " boardtype " is unknown"
- errors["unknown-unknown"]++;
- }
- }
-
- END { for (i in errors) {
- n = split(i,list,"-");
- printf "%d errors for board %s, chip %s\n",errors[i],list[1],list[2];
- }
- }
-